﻿// // ******************************************************************
// //       /\ /|       @file       TranslateQueryHandler.cs
// //       \ V/        @brief      await29
// //       | "")       @author     Await, 285283010@qq.com
// //       /  |
// //      /  \\        @Modified   2025-03-02 10:03
// //    *(__\_\        @Copyright  Copyright (c) , 2025-02-23 10:02 Await
// // ******************************************************************

using System.Linq.Expressions;
using AutomaticSubtitles.Contracts.Dto;
using AutomaticSubtitles.Contracts.Entity;
using AutomaticSubtitles.Contracts.Services;
using AutomaticSubtitles.Service.Application.Cahce.Queries;
using AutomaticSubtitles.Service.Application.Translate.Interface.Queries;
using AutomaticSubtitles.Service.Application.Translate.Queries;
using AutomaticSubtitles.Service.BackgroundServices;
using AutomaticSubtitles.Service.DataAccess.Model;
using AutomaticSubtitles.Service.Domain.Media;
using AutomaticSubtitles.Service.Domain.Translate;
using AutomaticSubtitles.Service.Infrastructure.BaiduTrans;
using AutomaticSubtitles.Service.Infrastructure.BaiduTrans.Model;

namespace AutomaticSubtitles.Service.Application.Translate;

public class TranslateQueryHandler(
    ITranslateRepository repository,
    IEventBus _eventBus,
    ITranslationService translationService,
    IMediaRepository mediaRepository,
    ILogger<TranslateQueryHandler>
        logger)
    : BaseAutoService
{
    [EventHandler]
    public async Task Handle(GetTranslationQuery query)
    {
        //判断字幕是否已经翻译过
        var result = await repository.GetTranslationRecordAsync(query.subtitle);
        query.Result = result;
    }

    [EventHandler]
    public async Task Hasndler(GetTranslationCorrectionsQuery query)
    {
        query.Result = query.translationValue;
        //TODO:翻译纠正 需要加吗？
        // var translateOptions = new GetConfigorderingQuery();
        // await _eventBus.PublishAsync(translateOptions);
        // foreach (var translateOption in translateOptions.Result)
        // {
        //     if (GlobalVariableEnumConfiguration.TranslationConfigurationEnum.AI != (GlobalVariableEnumConfiguration.TranslationConfigurationEnum)translateOption.Value) continue;
        //     var batchResults1 = await GetAITranslation(query.data, query.languageType, query.commandLanguageType);
        //     query.Result = batchResults1.;
        //
        //     break;
        // }
    }


    [EventHandler]
    public async Task Handle(GetExternalTranslation query)
    {
        //获取可以翻译选项，ai，百度翻译，本地翻译
        //测试数据选项,list<string> Ai,Baidu,Local
        // var translateOptions = new List<GlobalVariableEnumConfiguration.TranslationConfigurationEnum>
        // { GlobalVariableEnumConfiguration.TranslationConfigurationEnum.AI, GlobalVariableEnumConfiguration.TranslationConfigurationEnum.Baidu };
        var translateOptions = new GetConfigorderingQuery();
        await _eventBus.PublishAsync(translateOptions);
        foreach (var translateOption in translateOptions.Result)
            switch ((GlobalVariableEnumConfiguration.TranslationConfigurationEnum)translateOption.Value)
            {
                case GlobalVariableEnumConfiguration.TranslationConfigurationEnum.AI:
                    var batchResults1 = await GetAITranslation(query.data, query.languageType, query.commandLanguageType, query.compulsory);
                    query.Result = batchResults1;
                    return;
                case GlobalVariableEnumConfiguration.TranslationConfigurationEnum.Baidu:
                    // 获取百度翻译API配置
                    var batchResults = await GetBaiduTranslation(query.data, query.languageType, query.commandLanguageType, query.compulsory);
                    query.Result = batchResults;
                    return;
                case GlobalVariableEnumConfiguration.TranslationConfigurationEnum.Other:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
    }


    private async Task<(int Key, string)[]?> GetAITranslation(IEnumerable<KeyValuePair<int, string>> data, string? languageType, string? translatedLanguageType,
        bool compulsory = false)
    {
        var batchTasks = data.Select(async untranslatedSegment =>
        {
            try
            {
                // 跳过分隔符
                if (!compulsory && Common.SplitRegex.IsMatch(untranslatedSegment.Value)) return (untranslatedSegment.Key, untranslatedSegment.Value);


                //调用ai翻译
                var translationModel = new TranslationModel
                {
                    Value = untranslatedSegment.Value,
                    LanguageType = languageType ?? "auto",
                    TranslatedLanguageType = translatedLanguageType ?? "zh"
                };
                var translationResult = await translationService.TranslateAsync(translationModel);
                if (translationResult != null) return (untranslatedSegment.Key, translationResult.TranslatedValue);
                // return null;
                // logger.LogWarning($"--翻译失败，保持原文: {untranslatedSegment.Value}");
                // return (untranslatedSegment.Key, untranslatedSegment.Value);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"--翻译段落失败: {untranslatedSegment.Value}");
            }

            // return (untranslatedSegment.Key, untranslatedSegment.Value);
            return (untranslatedSegment.Key, null);
        });

        // 等待批次完成并处理结果
        var batchResults = await Task.WhenAll(batchTasks);
        return batchResults;
    }

    /// <summary>
    /// 提取百度翻译操作
    /// </summary>
    /// <param name="data">数据</param>
    /// <param name="languageType">源语言</param>
    /// <param name="translatedLanguageType">目标语言</param>
    /// <param name="compulsory">是否强制</param>
    /// <returns></returns>
    private async Task<(int Key, string)[]> GetBaiduTranslation(IEnumerable<KeyValuePair<int, string>> data, string? languageType, string? translatedLanguageType, bool
        compulsory = false)
    {
        // 获取百度翻译API配置
        var getCacheKeyBaiduTranslationApiConfigurationQuery = new GetCacheKeyBaiduTranslationAPIConfigurationQuery();
        await _eventBus.PublishAsync(getCacheKeyBaiduTranslationApiConfigurationQuery);
        var translationConfig = new BaiduTransOptionModel
        {
            AppId = getCacheKeyBaiduTranslationApiConfigurationQuery.Result.AppId,
            SecretKey = getCacheKeyBaiduTranslationApiConfigurationQuery.Result.SecretKey
        };

        var baiduTransApicSharpHelper = new BaiduTransApicSharpHelper(translationConfig);

        var batchTasks = data.Select(async untranslatedSegment =>
        {
            try
            {
                // 跳过分隔符
                if (!compulsory && Common.SplitRegex.IsMatch(untranslatedSegment.Value)) return (untranslatedSegment.Key, untranslatedSegment.Value);

                // 调用翻译服务
                var translationResult = await baiduTransApicSharpHelper.TranslateUsingExternalService(languageType,
                    untranslatedSegment.Value,
                    translatedLanguageType,
                    logger
                );

                if (!string.IsNullOrWhiteSpace(translationResult)) return (untranslatedSegment.Key, translationResult);

                logger.LogWarning($"--翻译失败，保持原文: {untranslatedSegment.Value}");
                return (untranslatedSegment.Key, untranslatedSegment.Value);
            }
            catch (Exception ex)
            {
                logger.LogError(ex, $"--翻译段落失败: {untranslatedSegment.Value}");
                return (untranslatedSegment.Key, untranslatedSegment.Value);
            }
        });

        // 等待批次完成并处理结果
        var batchResults = await Task.WhenAll(batchTasks);
        return batchResults;
    }


    [EventHandler]
    public async Task Handler(GetTranslateQuery query)
    {
        Expression<Func<Auto_Translate, bool>> queryWhere = x => x.Value == query.Value && x.TranslatedLanguageType == query.TranslatedLanguageType;
        if (!query.LanguageType.IsNullOrWhiteSpace()) queryWhere = queryWhere.And(x => x.LanguageType == query.LanguageType);
        var autoTranslates = (await repository.GetListAsync(queryWhere)).ToList();
        //找到那个被翻译的对象
        if (autoTranslates.Count != 0)
        {
            query.ValueShow = autoTranslates.First().TranslatedValue;
            query.Result = autoTranslates.MapToList<TranslateDto>();
            return;
        }

        var listAsync = (await repository.GetListAsync(queryWhere)).ToList();
        if (listAsync.Count != 0)
        {
            query.ValueShow = listAsync.First().TranslatedValue;
            query.Result = listAsync.MapToList<TranslateDto>();
        }
    }


    [EventHandler]
    public async Task Handler(GetTranslateListQuery query)
    {
        var paginatedListAsync = await repository.GetPaginatedListAsync(query.PaginatedOptions);
        query.Result = paginatedListAsync.Result.MapToList<TranslateDto>();
    }

    [EventHandler]
    public async Task Handler(GetTranslateByIdQuery query)
    {
        var paginatedListAsync = await repository.FindAsync(x => x.Id == query.Id);
        query.Result = paginatedListAsync?.MapTo<TranslateDto>();
    }

    [EventHandler]
    public async Task Handler(GetTranslateMediaTranslationQuery query)
    {
        var paginatedListAsync = await mediaRepository.FindAsync(x => x.Id == query.id);
        if (paginatedListAsync != null) TranslateBackgroundService.AddTranslateMedia(paginatedListAsync);
        query.Result = "追加成功！";
    }
}